package top.csmcool.musicapi.resource;

/*
 * @description
 * @date 2025/1/31
 * @author shijin
 * @version 1.0
 */

import cn.hutool.json.JSONObject;

import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import top.csmcool.musicapi.client.NeteaseClient;
import top.csmcool.musicapi.config.SystemProperties;
import top.csmcool.musicapi.domain.UserPlatformBindInfo;
import top.csmcool.musicapi.domain.Users;
import top.csmcool.musicapi.enums.PlatformEnum;
import top.csmcool.musicapi.model.api.navidrome.LyricLine;
import top.csmcool.musicapi.model.api.navidrome.SongCollection;
import top.csmcool.musicapi.model.api.netease.*;
import top.csmcool.musicapi.model.playlist.*;
import top.csmcool.musicapi.util.TreadLocalUtil;

import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;

@Component("netease")
@RequiredArgsConstructor
public class NeteaseResource implements MusicResource{

    private final SystemProperties systemProperties;
    private final NeteaseClient neteaseClient;

    @Override
    public List<PlayListMusicInfo> getTracks(TracksRequest requestRequest, Users users, UserPlatformBindInfo one) {
        List<PlayListMusicInfo> result = new LinkedList<>();
        // 获取token
        one = getUserPlatformBindInfo(users, one, systemProperties.getMusicUrl() + "/" + PlatformEnum.NETEASE.getCode());
        TreadLocalUtil.setUserPlatformBindInfoThreadLocal(one);
        JSONObject parameter = new JSONObject();
        parameter.set("id", requestRequest.getId());
        List<MusicTrack> list = neteaseClient.playlistDetail(parameter);

        for (MusicTrack musicTrack : list) {
            PlayListMusicInfo playListMusicInfo = new PlayListMusicInfo();
            playListMusicInfo.setId(String.valueOf(musicTrack.getId()));
            playListMusicInfo.setName(musicTrack.getName());
            String artists = musicTrack.getArtists().stream().map(Artist::getName).collect(Collectors.joining("/"));
            playListMusicInfo.setSinger(artists);
            playListMusicInfo.setAlbum(musicTrack.getAlbum().getName());
            playListMusicInfo.setImage(musicTrack.getAlbum().getPicUrl());
            playListMusicInfo.setDuration((long) (musicTrack.getDuration() / 1000));
            playListMusicInfo.setUrl(String.format("https://music.163.com/song/media/outer/url?id=%s.mp3", musicTrack.getId()));
            playListMusicInfo.setPlatform(PlatformEnum.NETEASE.getCode());
            playListMusicInfo.setPlatformName(PlatformEnum.NETEASE.getName());
            result.add(playListMusicInfo);
        }
        updateCookie();
        return result;
    }

    @Override
    public List<LyricInfo> getLyric(LyricRequest body, Users users, UserPlatformBindInfo one) {
        List<LyricInfo> lyricInfos = new LinkedList<>();

        // 获取token
        one = getUserPlatformBindInfo(users, one, systemProperties.getMusicUrl()  + "/" + PlatformEnum.NETEASE.getCode());
        TreadLocalUtil.setUserPlatformBindInfoThreadLocal(one);

        JSONObject parameter = new JSONObject();
        parameter.set("id", body.getId());
        String lyric = neteaseClient.lyric(parameter);
        if(StringUtils.hasText(lyric)) {
            lyricInfos = parseLyric(lyric);
        }

        return lyricInfos;
    }

    @Override
    public List<SongCollection> getPlayList(PlayListRequest body, Users users, UserPlatformBindInfo one) {
        List<SongCollection> songCollections = new LinkedList<>();

        // 获取token
        one = getUserPlatformBindInfo(users, one, systemProperties.getMusicUrl()  + "/" + PlatformEnum.NETEASE.getCode());
        TreadLocalUtil.setUserPlatformBindInfoThreadLocal(one);

        JSONObject parameter = new JSONObject();
        parameter.set("uid", one.getPlatformId());
        parameter.set("offset", body.getStart());
        parameter.set("limit", body.getSize());
        List<MusicPlayList> musicPlayLists = neteaseClient.userPlaylist(parameter);
        for (MusicPlayList musicPlayList : musicPlayLists) {
            SongCollection songCollection = getSongCollection(musicPlayList);
            songCollections.add(songCollection);
        }

        return songCollections;
    }

    @Override
    public List<SongCollection> getPublicPlayList(PlayListRequest body, Users users, UserPlatformBindInfo one) {
        List<SongCollection> songCollections = new LinkedList<>();
        // 获取token
        one = getUserPlatformBindInfo(users, one, systemProperties.getMusicUrl()  + "/" + PlatformEnum.NETEASE.getCode());
        TreadLocalUtil.setUserPlatformBindInfoThreadLocal(one);

        JSONObject parameter = new JSONObject();
        parameter.set("limit", 30);
        List<Playlist> playlists = neteaseClient.personalized(parameter);
        for (Playlist playlist : playlists) {
            SongCollection songCollection = new SongCollection();
            songCollection.setId(String.valueOf(playlist.getId()));
            songCollection.setName(String.valueOf(playlist.getName()));
            songCollection.setCoverImgUrl(playlist.getPicUrl());
            songCollection.setSongCount(playlist.getTrackCount());
        }

        return songCollections;
    }

    @Override
    public List<PlayListMusicInfo> search(SearchRequest body, Users users, UserPlatformBindInfo one) {
        List<PlayListMusicInfo> songs = new LinkedList<>();

        // 获取token
        one = getUserPlatformBindInfo(users, one, systemProperties.getMusicUrl()  + "/" + PlatformEnum.NETEASE.getCode());
        TreadLocalUtil.setUserPlatformBindInfoThreadLocal(one);

        JSONObject parameter = new JSONObject();
        parameter.set("keywords", body.getName());
        parameter.set("offset", body.getStart());
        parameter.set("limit", body.getSize());
        List<Song> songList = neteaseClient.search(parameter);
        for (Song song : songList) {
            PlayListMusicInfo playListMusicInfo = new PlayListMusicInfo();

            playListMusicInfo.setId(String.valueOf(song.getId()));
            playListMusicInfo.setName(song.getName());
            String name = song.getArtists().stream().map(Artist::getName).collect(Collectors.joining(","));
            playListMusicInfo.setSinger(name);
            if(song.getAlbum() != null) {
                playListMusicInfo.setAlbum(song.getAlbum().getName());
                playListMusicInfo.setImage(song.getAlbum().getPicUrl());
            }
            playListMusicInfo.setDuration((long) song.getDuration());
            playListMusicInfo.setUrl(String.format("https://music.163.com/song/media/outer/url?id=%s.mp3", song.getId()));

            songs.add(playListMusicInfo);
        }

        return songs;
    }

    @Override
    public SongInfo getSongUrl(SongUrlRequest body, Users users, UserPlatformBindInfo one) {
        SongInfo songInfo = new SongInfo();
        // 获取token
        one = getUserPlatformBindInfo(users, one, systemProperties.getMusicUrl()  + "/" + PlatformEnum.NETEASE.getCode());
        TreadLocalUtil.setUserPlatformBindInfoThreadLocal(one);

        cn.hutool.json.JSONObject parameter = new cn.hutool.json.JSONObject();
        parameter.set("id", body.getId());
        List<SongData> songData = neteaseClient.songUrl(parameter);

        if (songData == null || songData.isEmpty()) {
            return songInfo;
        }
        String url = songData.get(0).getUrl();
        songInfo.setSongUrl(url);
        return songInfo;
    }

    private SongCollection getSongCollection(MusicPlayList musicPlayList) {
        SongCollection songCollection = new SongCollection();
        songCollection.setId(String.valueOf(musicPlayList.getId()));
        songCollection.setCoverImgUrl(musicPlayList.getCoverImgUrl());
        songCollection.setName(musicPlayList.getName());
        songCollection.setComment(musicPlayList.getDescription());
        songCollection.setDuration(musicPlayList.getTotalDuration());
        songCollection.setSongCount(musicPlayList.getTrackCount());
        songCollection.setOwnerName(musicPlayList.getCreator().getNickname());
        songCollection.setOwnerId(String.valueOf(musicPlayList.getCreator().getUserId()));
        songCollection.setCreatedAt(String.valueOf(musicPlayList.getCreateTime()));
        songCollection.setUpdatedAt(String.valueOf(musicPlayList.getUpdateTime()));
        return songCollection;
    }

    @Override
    public JSONObject requestResource(JSONObject jsonObject, Users users, UserPlatformBindInfo one) {
        one = getUserPlatformBindInfo(users, one, systemProperties.getMusicUrl()  + "/" + PlatformEnum.NETEASE.getCode());
        TreadLocalUtil.setUserPlatformBindInfoThreadLocal(one);
        return neteaseClient.requestResource(jsonObject);
    }
}
